package com.example.controller;

import com.example.dto.MessageDto;
import com.example.entity.Order;
import com.example.entity.OrderSort;
import com.example.service.AsyncOrderService;
import com.example.service.FanoutProducerService;
import com.example.service.OrderService;
import com.example.service.PriorityMessageProducer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;


@Slf4j
@RestController
@RequestMapping("/test")
public class SendMessageController {
    @Autowired
    private OrderService orderService;

    @Autowired
    private AsyncOrderService asyncOrderService;

    @Autowired
    private PriorityMessageProducer priorityMessageProducer;
    /**
     * 1.测试普通的rabbitmq 发送订单创建消息
     * @param msg
     */
    @GetMapping("/createOrder/{msg}")
    public void createOrder(@PathVariable(value = "msg") String msg) {
        Order order = new Order(1L, msg, new BigDecimal("99.99"), LocalDateTime.now());
        orderService.createOrder(order);
        // 等待消息处理完成
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }


    /**
     * 2.发送带correlationData的消息
     * @param msg
     */

    @GetMapping("/createOrder1/{msg}")
    public void createOrder1(@PathVariable(value = "msg") String msg) {
        Order order = new Order(1L, msg, new BigDecimal("99.99"), LocalDateTime.now());
        orderService.createOrder1(order);
        // 等待消息处理完成
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }


    /**
     * 3.发送异常的消费者重试(默认次数)，不会进入死信队列
     * @param msg
     */
    @GetMapping("/createTryOrder/{msg}")
    public void createTryOrder(@PathVariable(value = "msg") String msg) {
        Order order = new Order(1L, msg, new BigDecimal("99.99"), LocalDateTime.now());
        orderService.createTryOrder(order);
        // 等待消息处理完成
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }


    /**
     * 4.发送异常的消费者重试(默认次数)，进入死信队列，自动的会进入，手动的会在重启的时候进入
     * @param msg
     */
    @GetMapping("/createMain1Order/{msg}")
    public void createMain1Order(@PathVariable(value = "msg") String msg) {
        Order order = new Order(1L, msg, new BigDecimal("99.99"), LocalDateTime.now());
        orderService.createMain1Order(order);
        // 等待消息处理完成
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }




    /**
     * 5.绑定带有死信队列的版本，发送异常的消费者重试(指定次数)，进入死信队列
     * @param msg
     */

    @GetMapping("/sendDlxMsg/{msg}")
    public void testCreateOrder(@PathVariable(value = "msg") String msg) {
        Order order = new Order(1L, msg, new BigDecimal("99.99"), LocalDateTime.now());
        orderService.createOrder2(order);
        // 等待消息处理完成
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }

    /**
     * 6.发送延迟消息 TTL + 死信队列
     * @param msg
     * @return
     */
    @GetMapping("/sendDelayMessage/{msg}")
    public String sendDelayMessage(@PathVariable(value = "msg") String msg) {

        log.info("send msg:" + msg);
        Order order = new Order(1L, msg, new BigDecimal("99.99"), LocalDateTime.now());
        orderService.sendDelayMessage1(order,30);
        // 等待消息处理完成
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        return "success";
    }

    /**
     * 7.发送延迟消息 RabbitMQ插件方案（rabbitmq-delayed-message-exchange）
     * @param msg
     * @return
     */

    @GetMapping("/sendDelayMessage1/{msg}")
    public String sendDelayMessage1(@PathVariable(value = "msg") String msg) {

        log.info("send msg:" + msg);
        Order order = new Order(1L, msg, new BigDecimal("99.99"), LocalDateTime.now());
        orderService.sendDelayMessage(order,30);
        // 等待消息处理完成
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        return "success";
    }


    /**
     *  8.发送优先级消息
     * @return
     */
    @GetMapping("/testPriorityMessages")
    public ResponseEntity<String> testPriorityMessages() {
        priorityMessageProducer.sendOrderMessages();
        return ResponseEntity.ok("优先级消息已发送");
    }


    /**
     * 9.发送批量消息
     */
    @GetMapping("/sendBatchMessage/{msg}")
    public String sendBatchMessage(@PathVariable(value = "msg") String msg) {

        log.info("send msg:" + msg);
        Order order = new Order(1L, msg, new BigDecimal("99.99"), LocalDateTime.now());
        orderService.sendBatchMessage(order);
        // 等待消息处理完成
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        return "success";
    }


    /**
     * 10.异步发送订单并等待回复
     * @param msg
     * @return
     * @throws ExecutionException
     * @throws InterruptedException
     */
    @GetMapping("/sendAsyncMsg/{msg}")
    public String sendAsyncMsg(@PathVariable(value = "msg") String msg) throws ExecutionException, InterruptedException {

        log.info("send msg:" + msg);
        Order order = new Order(1L, msg, new BigDecimal("99.99"), LocalDateTime.now());
        CompletableFuture<String> stringCompletableFuture = asyncOrderService.sendOrderAsync(order);
        String s = stringCompletableFuture.get();
        log.info("异步处理结果: {}", s);
        // 等待消息处理完成
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        return "success";
    }
    /**
     * 11.异步发送订单，不等待回复
     * @param msg
     * @return
     * @throws ExecutionException
     * @throws InterruptedException
     */

    @GetMapping("/sendOrderNoReplyAsync/{msg}")
    public String sendOrderNoReplyAsync(@PathVariable(value = "msg") String msg) throws ExecutionException, InterruptedException {

        log.info("send msg:" + msg);
        Order order = new Order(1L, msg, new BigDecimal("99.99"), LocalDateTime.now());
        asyncOrderService.sendOrderNoReplyAsync(order);
        return "success";
    }

    @Autowired
    private FanoutProducerService fanoutProducerService;

    /**
     * 12.广播消息
     * @param message
     * @return
     */
    @GetMapping("/send")
    public String sendFanoutMessage(@RequestParam(defaultValue = "这是一条广播消息") String message) {
        fanoutProducerService.sendFanoutMessage(message);
        return "广播消息发送成功: " + message;
    }

    /**
     * 13.广播消息 - 带对象
     * @param message
     * @return
     */

    @GetMapping("/send-object")
    public String sendFanoutObject() {
        // 发送一个简单的对象作为示例
        MessageDto messageDto = new MessageDto();
        messageDto.setContent("广播对象消息");
        messageDto.setType("fanout");
        fanoutProducerService.sendFanoutMessage(messageDto);
        return "广播对象消息发送成功";
    }


    /**
     * 14.发送顺序消息
     * @param
     * @return
     */

    @GetMapping("/sendSequenceMessage/{msg}")
    public String sendSequenceMessage(@PathVariable(value = "msg") String msg) {

        log.info("send msg:" + msg);
        Order order = new Order(1L, msg, new BigDecimal("99.99"), LocalDateTime.now());
        orderService.sendSequenceMessage(order);
        return "顺序消息发送成功";
    }
}